It wouldn’t be much fun if you couldn’t update data once you put it in
storage, would it? Thankfully, updating entities in Azure tables is
pretty simple once you get the hang of the various merge/conflict
options available.
Earlier, you saw how every query result returns with an ETag. This ETag corresponds to a specific version of the
entity. If the entity changes, the service will ensure that it gets a
new ETag. Updating an entity now
becomes a simple matter of retrieving entities, making changes on the
client side, and telling the server about your updates and what the
ETag was when you first retrieved the
entity to detect conflicts. This is similar to concurrency controls in
databases.
In .NET code, this is tightly integrated with the DataServiceContext. You have several “merge” options from which you can choose, as shown in
Table 1.
Table 1. Merge options
Merge
option | Description |
---|
AppendOnly | Client changes for new
entities are accepted, but changes to existing entities are not.
This is the default value where the entity isn’t loaded from the
server if it is present in the client cache. |
OverwriteChanges | Always update with values
from the server, overwriting any client changes. |
PreserveChanges | Client-side values that
have changed are preserved, but other values are updated from
the server. Also, when an entity instance exists on the client,
it is not loaded from the server. No client-side changes are
lost. When an object is updated, the ETag is updated as well, so this
catches any errors if changes have occurred on the server
without the client’s knowledge. |
NoTracking | There is no client-side
tracking. Values are always read from the storage source, and
any local changes are overwritten. |
In code, to update an entity, you typically follow these
steps:
Create a DataServiceContext
object, and set its merge option to one of the selections from Table 10-7. You could choose to leave the default
value (AppendOnly), because this
works well in normal scenarios.
Query for the entity you want to update.
Update the object representation of your entity in
code.
Call DataServiceContext.UpdateObject on the
objects you updated.
Call DataServiceContext.SaveChanges to push
changes back to the server.
Example 1 walks through a simple
query-update-save pattern.
Example 1. Simple update
CloudStorageAccount.Parse(ConfigurationSettings.AppSettings ["DataConnectionString"]); var svc = new TestDataServiceContext (account.TableEndpoint.ToString(), account.Credentials); svc.MergeOption = MergeOption.PreserveChanges; var query = from contact in svc.CreateQuery<Contact>("ContactTable") where contact.Name == "Steve Jobs" select contact; var foundContact = query.FirstOrDefault<Contact>(); foundContact.Address = "One Infinite Loop, Cupertino, CA 95014"; svc.UpdateObject(foundContact);
svc.SaveChanges();
|
The following HTTP traffic when SaveChanges is called shows this ETag matching mechanism clearly. You already
saw how querying for an item sends down an ETag, which is the server’s version of the
object. When SaveChanges is called,
you send out an update that says, “Update if it matches the earlier
ETag.” If successful, the server updates the entity and sends down a new
ETag.
HTTP Request (only headers shown)
MERGE /ContactTable(PartitionKey='a844fa27-7ae2-4894-9cc6-dd0dbdcd5ec4',
RowKey='') HTTP/1.1
User-Agent: Microsoft ADO.NET Data Services
x-ms-date: Tue, 21 Apr 2009 16:57:29 GMT
Authorization: SharedKeyLite sriramk:HVNqyS/X/AhqFxhnRKSe0SXTDSzJssFyk9JiyQvwnO4=
Accept: application/atom+xml,application/xml
Accept-Charset: UTF-8
DataServiceVersion: 1.0;NetFx
MaxDataServiceVersion: 1.0;NetFx
Content-Type: application/atom+xml
If-Match: W/"datetime'2009-04-21T06%3A38%3A28.242Z'"
Host: sriramk.table.core.windows.net
Content-Length: 864
HTTP Response
HTTP/1.1 204 No Content
Cache-Control: no-cache
Content-Length: 0
ETag: W/"datetime'2009-04-21T16%3A56%3A29.717Z'"
Server: Table Service Version 1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 05a9f45f-bab9-417a-89b6-fc7759f31b2f
Date: Tue, 21 Apr 2009 16:56:35 GMT